//
//  ShapProgressView.swift
//  SharpProgress
//
//  Created by tianqi on 2017/11/10.
//  Copyright © 2017年 david.com. All rights reserved.
//

import UIKit

class ShapProgressView: UIView {
    
    fileprivate var _originFrame: CGRect!
    fileprivate var _progressHeight: CGFloat = 20.0
    fileprivate var _progressWidth: CGFloat!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
        backgroundColor = UIColor.orange
        layer.cornerRadius = bounds.size.width * 0.5
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
    }
    
    /// 1
    func startAnimation() {
        
        _originFrame = self.frame
        _progressWidth = _originFrame.width * _originFrame.height / _progressHeight// 面积不变
        
        self.layer.cornerRadius = self._progressHeight * 0.5
        let animation1 = CABasicAnimation(keyPath: "cornerRadius")
        animation1.duration = 0.4
        animation1.fromValue = bounds.size.width * 0.5
        animation1.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
        animation1.isRemovedOnCompletion = false
        animation1.fillMode = kCAFillModeForwards
        animation1.delegate = self
        layer.add(animation1, forKey: "animation1")
    }
    
    /// 2
    func progressAnimation() {
        
        let path = UIBezierPath()
        path.move(to: CGPoint(x: _progressHeight * 0.5, y: bounds.height * 0.5))
        path.addLine(to: CGPoint(x: _progressWidth - _progressHeight * 0.5, y: bounds.height * 0.5))
        
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        shapeLayer.lineWidth = _progressHeight - 4
        shapeLayer.lineCap = kCALineCapRound
        shapeLayer.strokeColor = UIColor.red.cgColor
        layer.addSublayer(shapeLayer)
        
        let progressAm = CABasicAnimation(keyPath: "strokeEnd")
        progressAm.duration = 1.0
        progressAm.fromValue = 0
        progressAm.toValue = 1
        progressAm.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
        progressAm.delegate = self
        shapeLayer.add(progressAm, forKey: "progressAm")
    }
    
    // 4
    func checkAnimation() {
        
        let path = UIBezierPath()
        let littleRect = bounds.insetBy(dx: bounds.width * (1 - 1 / sqrt(2)) * 0.5, dy: bounds.height * (1 - 1 / sqrt(2)) * 0.5)
        path.move(to: CGPoint(x: littleRect.origin.x + littleRect.width / 10, y: littleRect.origin.y + littleRect.height * 2 / 3))
        path.addLine(to: CGPoint(x: littleRect.origin.x + littleRect.width / 3 , y: littleRect.origin.y + littleRect.height * 9 / 10))
        path.addLine(to: CGPoint(x: littleRect.origin.x + littleRect.width * 8 / 10, y: littleRect.origin.y + littleRect.width * 2 / 10))
        
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        shapeLayer.lineWidth = 8
        shapeLayer.lineCap = kCALineCapRound
        shapeLayer.lineJoin = kCALineJoinRound
        shapeLayer.strokeColor = UIColor.white.cgColor
        shapeLayer.fillColor = UIColor.clear.cgColor
        layer.addSublayer(shapeLayer)
        
        let checkAm = CABasicAnimation(keyPath: "strokeEnd")
        checkAm.duration = 0.3
        checkAm.fromValue = 0
        checkAm.toValue = 1
        checkAm.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
        shapeLayer.add(checkAm, forKey: "checkAm")
    }
}

extension ShapProgressView: CAAnimationDelegate {
    
    func animationDidStart(_ anim: CAAnimation) {
        // 1.1
        if anim == layer.animation(forKey: "animation1") {
            
            UIView.animate(withDuration: 0.45, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
                self.bounds = CGRect(x: 0, y: 0, width: self._progressWidth, height: self._progressHeight)
            }, completion: { (_) in
                self.layer.removeAllAnimations()
                self.progressAnimation()
            })
        }else if anim == layer.animation(forKey: "animation2") {
            
            // 3.1
            UIView.animate(withDuration: 0.35, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: { 
                self.bounds = CGRect(x: 0, y: 0, width: self._originFrame.width, height: self._originFrame.height)
            }, completion: { (_) in
                self.layer.removeAllAnimations()
                self.checkAnimation()
            })
        }
    }
    
    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        
        if let am = anim as? CABasicAnimation, let keypath = am.keyPath, keypath == "strokeEnd" {
            self.layer.removeAllAnimations()
            
            UIView.animate(withDuration: 0.2, animations: {
                self.layer.sublayers?.forEach({ (ly) in
                    ly.opacity = 0.0
                })
            }, completion: { (_) in
                self.layer.sublayers?.forEach({ (ly) in
                    ly.removeFromSuperlayer()
                })
                self.backgroundColor = UIColor.red
            })
            
            // 3
            layer.cornerRadius = _originFrame.height * 0.5
            let animation2 = CABasicAnimation(keyPath: "cornerRadius")
            animation2.duration = 0.3
            animation2.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
            animation2.isRemovedOnCompletion = false
            animation2.fillMode = kCAFillModeForwards
            animation2.delegate = self
            layer.add(animation2, forKey: "animation2")
        }
    }
}
